'''
Created on 10.10.2012

@author: doleynik
'''
import cgi
import json
import time
import webapp2
import datetime

from webapp2_extras.i18n import gettext as _

from google.appengine.api import users
from apnetmodels.basicmodels import lot, lot_owner, lot_budget_weights, immeuble, lot_types 
from common import functions
from wtforms.ext.appengine.db import model_form
from BaseHandler import BaseHandler

class Lots(BaseHandler):
    def __init__(self, *args, **kwargs):
        super(Lots, self).__init__(*args, **kwargs)
        self.au = functions.GetAPNETUser()
        if not self.au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        self.fields = {
                       'immeuble': _('Tenement'), 'number': _('Lot number'), 'lot_type': _('Type'), 'batiment': _('Building'),
                       'escalier': _('Entree'), 'etage': _('Floor'), 'surface': _('Surface'), 'nbpieces': _('Number of items'),
                       'plan': _('Plan'), 'occupant': _('Resident'), 'codeedf': _('EDF code'), 'codegdf': _('GDF code'),
                       'codetelecom': _('Telecom code'), 'have_owner': _('Lot has current owner'), 'owner': _('Owner')
                       }
    
    def get(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)

    def post(self, *args, **kwargs):
        self.get_method(self.__class__, *args, **kwargs)
    
    def op_list(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        template_values = {
            'title': _('List of lots. %s' % imm.name),
            'header': _('%s. List of Lots' % imm.name),
            'app_user': self.au,
            'immeuble': imm,
            'section': 'creation',
            'leftmenu': 'lots',
            'lurl': users.create_logout_url('/'),
            'fields': self.fields
        }

        template = self.jinja2.get_template('templates/lots_list.html')
        self.response.out.write(template.render(template_values))
    
    def op_list_json(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            return
        
        lots = imm.lot_set.order('batiment').order('number').run()
        lo = []
        for l in lots:
            lo.append([l.number, unicode(l.batiment), unicode(l.lot_type), l.escalier, l.etage, l.surface, unicode(l.key().id())])
        
        ret = {}
        ret['aaData'] = lo
        self.response.out.write(json.dumps(ret))
  
    def op_list_names_json(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            return
        
        lots = imm.lot_set.order('number')
        l = []
        for lot in lots:
            l.append(str(lot))
        
        self.response.out.write(json.dumps(l))
    
    def op_list_wo_owners_json(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            return
        
        lots = imm.lot_set.filter('have_owner =', False).order('number').run()
        lwoo = []
        for l in lots:
            lwoo.append([l.number, unicode(l.batiment), str(l.lot_type), l.escalier, l.etage, l.surface, str(l.key().id())])
        
        ret = {}
        ret['aaData'] = lwoo
        self.response.out.write(json.dumps(ret))
        
    def op_add(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        
        ok_message = ''
        LotForm = model_form(lot, exclude=['lastchange_by','immeuble','have_owner'])
        
        if self.request.method == 'GET':
            form = LotForm()
            form['lot_type'].query = imm.syndic.lt_syndic_set.order('groupe').order('name')
            
        if self.request.method == 'POST':
            form = LotForm(self.request.POST)
            form['lot_type'].query = imm.syndic.lt_syndic_set.order('groupe').order('name')
            
            if form.validate():
                save = True
                
                if imm.lot_set.filter('number =', form['number'].data).get():
                    save = False
                    msg = _('Lot number already registered, please input another.')
                    form['number'].errors.append(msg)
                if save:
                    new_lot = lot(lastchange_by = self.au, 
                                  immeuble = imm, 
                                  lot_type = form['lot_type'].data,
                                  occupant = form['occupant'].data,
                                  number = form['number'].data,
                                  batiment = form['batiment'].data,
                                  etage = form['etage'].data,
                                  escalier = form['escalier'].data,
                                  plan = form['plan'].data,
                                  surface = form['surface'].data,
                                  codeedf = form['codeedf'].data,
                                  codegdf = form['codegdf'].data,
                                  codetelecom = form['codetelecom'].data)
                    new_lot.put()
                    while not new_lot.is_saved():
                        time.sleep(2)
                    ok_message = _('Lot was added.')
        
        template_values = {
            'form': form, 
            'ok_message': ok_message,
            'fields': self.fields
        }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
    
    def op_edit(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        lot_id = kwargs.get('lot_id', -1)
        
        ok_message = ''
        
        l_obj = lot.get_by_id(int(lot_id))
        if not l_obj:
            self.object_does_not_exist()
            return
        
        LotForm = model_form(lot, exclude=['lastchange_by','immeuble','have_owner'])
            
        if self.request.method == 'GET':
            form = LotForm(obj=l_obj)
            form['lot_type'].query = lot_types.all().filter('syndic =', l_obj.immeuble.syndic)
            
        if self.request.method == 'POST':
            form = LotForm(self.request.POST)
            if form.validate():
                save = True
                l = l_obj.immeuble.lot_set.filter('number =', form['number'].data).get()
                if l and l.key() != l_obj.key():
                    save = False
                    msg = _('Lot number already registered, please input another.')
                    form['number'].errors.append(msg)
                if save:
                    l_obj.lastchange_by = self.au 
                    l_obj.lot_type = form['lot_type'].data
                    l_obj.occupant = form['occupant'].data
                    l_obj.number = form['number'].data
                    l_obj.batiment = form['batiment'].data
                    l_obj.etage = form['etage'].data
                    l_obj.escalier = form['escalier'].data
                    l_obj.plan = form['plan'].data
                    l_obj.surface = form['surface'].data
                    l_obj.codeedf = form['codeedf'].data
                    l_obj.codegdf = form['codegdf'].data
                    l_obj.codetelecom = form['codetelecom'].data
                    l_obj.put()
                    while not l_obj.is_saved():
                        time.sleep(2)
    
                    ok_message = _('Lot was saved.')
                
        template_values = {
            'form': form, 
            'ok_message': ok_message,
            'fields': self.fields
        }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))

    def op_delete(self, *args, **kwargs):
        imm_id = kwargs.get('imm_id', -1)
        lot_id = kwargs.get('lot_id', -1)
        imm = immeuble.get_by_id(int(imm_id))
        
        ok_message = ''
        alert_message = ''
        
        l_obj = lot.get_by_id(int(lot_id))
        if not l_obj:
            self.object_does_not_exist()
            return
        
        if self.request.method == 'GET':
            alert_message = _('Are you sure you want to delete lot: %s?' % l_obj)
            
        if self.request.method == 'POST':
            delete = True
            if l_obj.owner_lots.get() or l_obj.lotsckeys.get():
                delete = False
                alert_message = _("Deletion for this lot restricted, due to there are related data already in system. Deletion rejected." )
                
            if delete:
                l_obj1 = l_obj
                l_obj.delete()
                while not l_obj1 is None:
                    l_obj1 = lot.get_by_id(int(lot_id))
                    time.sleep(1)
                ok_message = _('Lot was deleted.')
                
        template_values = {
            'ok_message': ok_message,
            'alert_message': alert_message,
            'fields': self.fields
        }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))

class LotDetail(BaseHandler):
    def show(self, imm_id, lot_id):
        au = functions.GetAPNETUser()
        if au:
            l_obj = lot.get_by_id(int(lot_id))
            if not l_obj:
                self.redirect(webapp2.uri_for('mainpage'))
                return

            LotForm = model_form(lot, exclude=['lastchange_by']) 
            l = LotForm(obj=l_obj) 
            owners =  lot_owner.all().filter('lot =', l_obj).run()
            weights = lot_budget_weights.all().filter('lot =', l_obj).run()
            
            template_values = {
                                   'title': _('Lot details'),
                                   'header': _('%s. Lot information' % l_obj.immeuble.name),
                                   'lot_id': l_obj.key().id(),
                                   'lot_form': l,
                                   'lot': l_obj,
                                   'owners': owners,
                                   'bweights': weights,
                                   'app_user': au,
                                   'lurl': users.create_logout_url('/'),
                                   'fields': self.fields
                                   }
            template = self.jinja2.get_template('templates/lot_detail.html')
            self.response.out.write(template.render(template_values))
            
        else:
            self.redirect('/')


    def get(self, imm_id, lot_id):
        self.show(imm_id, lot_id)
        
    def post(self, imm_id, lot_id):
        self.show(imm_id, lot_id)        
    
class TantiemeAdd(BaseHandler):
    def show(self, imm_id, lot_id):
        au = functions.GetAPNETUser()
        if not au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        
        l = lot.get_by_id(int(lot_id))
        if not l:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        ok_message = ''
        #weights = lot_budget_weights.all().filter('lot =', l).run()
        TantiemeForm = model_form(lot_budget_weights, exclude=['lot', 'lastchange_by', 'lastchange_date'])
        if self.request.method == 'GET':
            form = TantiemeForm()
            form['charges_key'].query = l.immeuble.get_charges_key_list()
            
        if self.request.method == 'POST':
            form = TantiemeForm(self.request.POST)
            form['charges_key'].query = l.immeuble.get_charges_key_list()
            if form.validate():
                new_budget_weight = lot_budget_weights(key_name = form['charges_key'].data.code + '_' + str(l.key().id()),
                                                       lot = l, 
                                                       charges_key = form['charges_key'].data, 
                                                       tantieme = form['tantieme'].data,
                                                       lastchange_by = au) 
                new_budget_weight.put()
                while not new_budget_weight.is_saved():
                    time.sleep(2)
      
                ok_message = _('Lot weight was added.')
        
        template_values = {
                           'form': form,
                           'ok_message': ok_message,
                           'fields': self.fields
                           }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
    
    def get(self, imm_id, lot_id):
        self.show(imm_id, lot_id)
        
    def post(self, imm_id, lot_id):
        self.show(imm_id, lot_id)


class TantiemeEdit(BaseHandler):
    def show(self, imm_id, lot_id, w_key):
        au = functions.GetAPNETUser()
        if not au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        
        l = lot.get_by_id(int(lot_id))
        if not l:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        ok_message = ''
        TantiemeForm = model_form(lot_budget_weights, exclude=['lot', 'lastchange_by', 'lastchange_date'])
        if self.request.method == 'GET':
            edit_budget_weight = lot_budget_weights.get(w_key)
            form = TantiemeForm(obj=edit_budget_weight)
            form['charges_key'].query = l.immeuble.get_charges_key_list()
            
        if self.request.method == 'POST':
            form = TantiemeForm(self.request.POST)
            form['charges_key'].query = l.immeuble.get_charges_key_list()
            
            if form.validate():
                edit_budget_weight = lot_budget_weights(key_name = form['charges_key'].data.code + '_' + str(l.key().id()),
                                                       lot = l, 
                                                       charges_key = form['charges_key'].data, 
                                                       tantieme = form['tantieme'].data,
                                                       lastchange_by = au) 
                edit_budget_weight.put()
                while not edit_budget_weight.is_saved():
                    time.sleep(2)

                ok_message = _('Lot weight was updated.')
        
        template_values = {
                           'form': form,
                           'ok_message': ok_message,
                           'fields': self.fields
                           }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
    
    def get(self, imm_id, lot_id, w_key):
        self.show(imm_id, lot_id, w_key)
        
    def post(self, imm_id, lot_id, w_key):
        self.show(imm_id, lot_id, w_key)
        
class LotOwners(BaseHandler):
    def __init__(self, *args, **kwargs):
        super(LotOwners, self).__init__(*args, **kwargs)
        self.fields = {
                       'owner': _('Owner'), 'code': _('Group code'), 'share': _('Share'), 'lot': _('Lot'),
                       'purchase_date': _('Date of purchase'), 'sale_date': _('Date of sale'), 'lot_number': _('Lot number'),
                       'immeuble': _('Tenement'), 'is_linked': _('Linked'), 'is_current_owner': _('Current owner'),
                       'occupant': _('Resident'), 'number': _('Lot number'), 'building': _('Building'), 'escalier': _('Lift'),
                       'etage': _('Floor'), 'surface': _('Surface')
                       }
    def get(self, imm_id, command, lo_id=None):
        if command == 'list':
            self.op_list(imm_id)
        elif command == 'list_json':
            self.op_list_json(imm_id)
        elif command == 'edit':
            self.op_edit(imm_id, lotowner_id = lo_id)
        elif command == 'add':
            self.op_add(imm_id, lotowner_id = lo_id)
        else:
            self.op_list(imm_id)

    def post(self, imm_id, command, lo_id=None):
        if command == 'edit':
            self.op_edit(imm_id, lotowner_id = lo_id)
        if command == 'add':
            self.op_add(imm_id, lotowner_id = lo_id)
    
    def op_add(self, imm_id, lotowner_id):
        au = functions.GetAPNETUser()
        if not au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        
        ok_message = ""
        lo_name = ""
        code = ""
        if lotowner_id:
            f_lotowner = model_form(lot_owner, exclude=['owner', 'code','share','immeuble','is_linked','is_current_owner',
                                                    'lastchange_by','lastchange_date','sale_date'])
            lo = lot_owner.get_by_id(int(lotowner_id))
            l_owner = lo.owner
            lo_name = unicode(l_owner)
            if lo.code:
                lo_name += " ["+ lo.code+ "]"
                code = lo.code
        else:
            f_lotowner = model_form(lot_owner, exclude=['share','immeuble','is_linked','is_current_owner',
                                                    'lastchange_by','lastchange_date','sale_date'])
        
        if self.request.method == 'GET':
            form = f_lotowner()
            if not lotowner_id:
                form['owner'].query = imm.syndic.syndic_contacts
            form['lot'].query = imm.lot_set.filter('have_owner =', False).order('number')
            
        if self.request.method == 'POST':
            form = f_lotowner(self.request.POST)
            if not lotowner_id:
                form['owner'].query = imm.syndic.syndic_contacts
            form['lot'].query = imm.lot_set.filter('have_owner =', False).order('number')
            
            if form.validate():
                linked = True
                owner = True
                save = True
                if not form['lot'].data:
                    linked = False
                    owner = False
                else:
                    if not form['purchase_date'].data:
                        save = False
                        ok_message = _('Some data is wrong.')
                        form['purchase_date'].errors.append(_('Purchase date should be defined'))
                if not lotowner_id:
                    l_owner = form['owner'].data
                    code = form['code'].data
                if imm.lot_owner_set.filter('owner = ', l_owner).filter('code =', code).filter('lot =', None).count() > 0:
                    save = False
                if save:
                    new_lot_owner = lot_owner( immeuble = imm,
                                               lot = form['lot'].data, 
                                               owner=l_owner, 
                                               code=code,
                                               purchase_date = form['purchase_date'].data,
                                               is_linked = linked, 
                                               is_current_owner = owner,
                                               lastchange_by = au)
                    new_lot_owner.put()
                    while not new_lot_owner.is_saved():
                        time.sleep(2)
                    if linked:
                        new_lot_owner.lot.have_owner = True
                        new_lot_owner.lot.put()
                    ok_message = "Lot owner saved"
                
        template_values = {
                           'form': form,
                           'ok_message': ok_message,
                           'fields': self.fields,
                           'person': lo_name
                           }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))
    
    def op_edit(self, imm_id, lotowner_id):
        au = functions.GetAPNETUser()
        if not au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        
        imm = immeuble.get_by_id(int(imm_id))
        if not imm:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        try:
            lotowner_obj = lot_owner.get_by_id(int(lotowner_id))
        except:
            lotowner_obj = None
        if not lotowner_obj:
            self.redirect(webapp2.uri_for('mainpage'))
            return
        ok_message = ""
        person_name = unicode(lotowner_obj.owner)
        if lotowner_obj.code:
            person_name += ' [' + lotowner_obj.code + ']'
        lot_q =  imm.lot_set.filter('have_owner =', False).order('number')
        lot_set = []

        for l in lot_q.run():
            lot_set.append(l)
        if lotowner_obj.lot:
            lot_set.append(lotowner_obj.lot)

        if lotowner_obj.sale_date:
            f_lotowner = model_form(lot_owner, exclude=['owner','code','lot','purchase_date','share','immeuble','is_linked','is_current_owner',
                                                    'lastchange_by','lastchange_date'])
            person_name += ' lot: ' + unicode(lotowner_obj.lot) 
        else:
            f_lotowner = model_form(lot_owner, exclude=['owner','share','immeuble','is_linked','is_current_owner',
                                                    'lastchange_by','lastchange_date'])
        if self.request.method == 'GET':
            form = f_lotowner(obj=lotowner_obj)
            if not lotowner_obj.sale_date:
                form['lot'].query = lot_set
        
        if self.request.method == 'POST':
            form = f_lotowner(self.request.POST)
            if not lotowner_obj.sale_date:
                form['lot'].query = lot_set
            
            if form.validate():
                save = True
                is_owner = True
                if form['sale_date'].data and form['purchase_date']:
                    is_owner = False
                linked = True
                if not form['lot'].data:
                    linked = False
                    form['purchase_date'].data = None
                    form['sale_date'].data = None
                else:
                    if not form['purchase_date'].data:
                        save = False
                        ok_message = _('Some data is wrong.')
                        form['purchase_date'].errors.append(_('Purchase date should be defined'))
                    else:
                        if form['sale_date'].data:
                            if form['sale_date'].data < form['purchase_date'].data:
                                save = False
                                ok_message = _('Some data is wrong.')
                                form['sale_date'].errors.append(_('Sale date should be later than purchase date'))
                        else:
                            if not form['purchase_date'].data:
                                save = False
                                ok_message = _('Some data is wrong.')
                                form['purchase_date'].errors.append(_('Purchase date should be defined'))
                            
                if save:
                    
                    if lotowner_obj.lot and form['lot'].data:
                        if not lotowner_obj.lot.key() == form['lot'].data.key(): 
                            lotowner_obj.lot.have_owner = False
                            lotowner_obj.lot.put()
                    elif not form['lot'].data and lotowner_obj.lot:
                            lotowner_obj.lot.have_owner = False
                            lotowner_obj.lot.put()
                    
                    lotowner_obj.lot=form['lot'].data
                    lotowner_obj.code=form['code'].data 
                    lotowner_obj.purchase_date = form['purchase_date'].data
                    lotowner_obj.sale_date = form['sale_date'].data
                    lotowner_obj.is_current_owner = is_owner
                    lotowner_obj.is_linked = linked
                    lotowner_obj.put()
                    if lotowner_obj.lot and lotowner_obj.sale_date:
                        lotowner_obj.lot.have_owner = False
                        lotowner_obj.lot.put()
                    elif lotowner_obj.lot:
                        lotowner_obj.lot.have_owner = True
                        lotowner_obj.lot.put()
                    
                           
                    ok_message = "Lot owner saved"

        template_values = {
                           'form': form,
                           'person': person_name,
                           'ok_message': ok_message,
                           'fields': self.fields
                           }
        
        template = self.jinja2.get_template('templates/base_form.html')
        self.response.out.write(template.render(template_values))

    def op_list(self, imm_id):
        au = functions.GetAPNETUser()
        if not au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        
        imm = immeuble.get_by_id(int(imm_id))  
        lo_l = []
        ok_message = ''
        for lot in imm.lot_set.run():
            for lo in lot.owner_lots.run():
                lo_l.append(lo.owner)
      
        template_values = {
            'title': _('Lot owners. %s' % imm.name),
            'header': _('%s. Lot owners.' % imm.name),
            'app_user': au,
            'immeuble': imm,
            'ok_message': ok_message,
            'section': 'creation',
            'leftmenu': 'lotowners',
            'lurl': users.create_logout_url('/'),
            'fields': self.fields
        }

        template = self.jinja2.get_template('templates/lot_owners_list.html')
        self.response.out.write(template.render(template_values))      

    def op_list_json(self, imm_id):
        au = functions.GetAPNETUser()
        if not au:
            self.redirect(users.create_login_url(self.request.uri))
            return
        
        imm = immeuble.get_by_id(int(imm_id))  
        lo_l = []
        for lo in imm.lot_owner_set.run():
            lot_number = None
            occupant = None
            if lo.lot:
                lot_number = lo.lot.number
                occupant = lo.lot.occupant
            purchase_date = None
            if lo.purchase_date:
                purchase_date = lo.purchase_date.strftime('%d/%m/%Y')
            sale_date = None    
            if lo.sale_date:
                sale_date = lo.sale_date.strftime('%d/%m/%Y')
            
            if not lo.sale_date or lo.sale_date > datetime.date.today() - datetime.timedelta(days=365): 
                lo_l.append([unicode(lo.owner), lo.code, lot_number, purchase_date, sale_date, unicode(occupant), str(lo.key().id()), str(lo.key().id())])

        ret = {}
        ret['aaData'] = lo_l
        self.response.out.write(json.dumps(ret))  



